#    Copyright 2008, 2009 Tri-County Electric Cooperative, St. Matthews, South Carolina
#    This file is part of COOPGIS.
#    COOPGIS is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    COOPGIS is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with COOPGIS.  If not, see <http://www.gnu.org/licenses/>.

import os
import datetime
FTPFileName='/opt/coopgis/fromgps/anonymousftproot_OtherReadOnly/incomingftpallpermissions/Locations.csv'
import shutil

#************************BEGIN Add Include Files to Path************************
import sys
NeededPaths=['/opt/coopgis/djangoproject/include', '/opt/coopgis/djangoproject']
for path in NeededPaths:
    if(not path in sys.path):
        sys.path.append(path)
#************************END   Add Include Files to Path************************
from django.contrib.gis.geos import *
import os, time, psycopg2, datetime
#********************Setup psycopg2 and django section********************
PathDjangoRoot="/opt/coopgis/"
if(not PathDjangoRoot in sys.path):
    sys.path.append(PathDjangoRoot)
import djangoproject
from djangoproject import settings
from djangoproject.models import *
#********************Setup psycopg2 and django section********************

from django.template import Context, loader
from django.http import HttpResponse
from django import forms
import os, pickle
import datetime
import djangoproject.settings
import COOPGIS_Misc
import cPickle

#Update Process Overview		Last Modified 11/13/2009
#The following is the update process overview on the Client: 
#  1)  User Clicks Update on the client
#  2)  in Update.py, ClientStartUpdate() is called
#  3)  ClientStartUpdate Creates a unique update number based on the date/time.
#  4)  COOPGIS_Update.ClientPerformUpdateTasks(UpdateNumber) is called to begin the update process
#  5)  A List of Commands to send to the Server is gathered by ClientGenerateExportCommandStringList()
#  5.1) ClientSendCommandsToServer(CommandStringList, UpdateNumber) actually sends the commands
#  6)  The Server is told to load the commands by ClientInstructServerToLoadCommands(UpdateNumber, CommandsToExport.count())
#  7)  Set ResidesOnServerIndicator for all commands in ClientSetCommandsAsResidingOnServer(CommandsToExport)
#  8)  Tell the Server to Process the commands in ClientTellServerToProcessCommands
#  9)  Tell the Server to Refresh the Download Repository in ClientTellServerToRefreshDownloadRepository()  
#  10)  ClientDownloadUpdatedRepository() is called, downloads updated files from the Server 
#  10.1)  Updates ServerIndicator in newly downloaded repository
#  10.2)  Makes a couple of misc folders (empty) and sets some permissions
#  11)  ClientInstallUpdatedDatabase() drops, creates, and reloads the COOPGIS DB, w/ Proper delays, sync
#  12)  ClientUpdateBluetoothMacAddressIfNeeded(), in nonvirtualmachines, creates the connect to bluetooth script
#  12.1)  Uses previously saved BluetoothMacAddress for this computer
#  13)  ClientCopyImageFiles() copies background images and such from COOPGIS directories to /var/www/ (web root)
#  14)  Client Reboots


#The following is the update process overview on the Server:
#  6.1)  ServerImportCommands(request, UpdateNumber=None) View is called by the client
#  6.2)  Wait until any updates that are in process have been imported
#  6.3)  Import Commands to Command table, return number of commands imported
#  8.1)  ServerProcessCommands(request, UpdateNumber) View is called by the client
#  8.2)  Commands for this update number are processed
#  8.3)  return index(request)  #Returns rendered Main Menu Page
#  9.1)  ServerUpdateRepository(request) View is called by the client
#  9.2)  Set ResidesOnServerIndicator to True for All Objects as a precaution
#  9.3)  COOPGIS_Update.ServerProtectedDumpDatabaseAndPullRepository() is called
#  9.3.1)  This dumps the database (1 database dump at a time, w/ 30 second delay)
#  9.3.2)  Updated Coopgis goes to /var/www/downloadrepository/IPAddress/... (coopgis...)
#  9.4)  Returns ServerUpdateRepository Template

#  9.1)  #Alternative Process:  FIXME, server needs to instead:
#  9.2)  SAME
#  9.3)  SAME
#  9.3.1) Dumps the database into an IP Address specific directory
#  9.3.2) Copies coopgis directory and all subdirectories over to this new location


def SetResidesOnServerIndicatorToTrueForAllCommands():
    UpdateResidesOnServerIndicatorAndSave(Command.objects.all().exclude(CommandResidesOnServerIndicator=True))
    UpdateResidesOnServerIndicatorAndSave(Assembly.objects.all().exclude(ResidesOnServerIndicator=True))
    UpdateResidesOnServerIndicatorAndSave(PoleJointUse.objects.all().exclude(ResidesOnServerIndicator=True))
    UpdateResidesOnServerIndicatorAndSave(Span.objects.all().exclude(ResidesOnServerIndicator=True))
    UpdateResidesOnServerIndicatorAndSave(Station.objects.all().exclude(ResidesOnServerIndicator=True))
    UpdateResidesOnServerIndicatorAndSave(Road.objects.all().exclude(ResidesOnServerIndicator=True))
    UpdateResidesOnServerIndicatorAndSave(BoardDistrict.objects.all().exclude(ResidesOnServerIndicator=True))
    UpdateResidesOnServerIndicatorAndSave(VegetationManagerJob.objects.all().exclude(ResidesOnServerIndicator=True))
    UpdateResidesOnServerIndicatorAndSave(VegetationManagerJobStatus.objects.all().exclude(ResidesOnServerIndicator=True))
    UpdateResidesOnServerIndicatorAndSave(VegetationManagerCrew.objects.all().exclude(ResidesOnServerIndicator=True))
    UpdateResidesOnServerIndicatorAndSave(VegetationManagerJobSpan.objects.all().exclude(ResidesOnServerIndicator=True))
    UpdateResidesOnServerIndicatorAndSave(StakerWorkOrder.objects.all().exclude(ResidesOnServerIndicator=True))

def UpdateResidesOnServerIndicatorAndSave(ListOfObjects):
    for i in ListOfObjects:
        i.ResidesOnServerIndicator=True
        i.CommandResidesOnServerIndicator=True
        i.save()

def ClientTellServerToRefreshDownloadRepository():
    WriteUpdateStatus('Requesting Server to Update the Repository with the Latest Code and Database, will wait until DatabaseDumpInProgress.txt does not exist')
    os.system("sudo -u apachescript sudo wget -O " + djangoproject.settings.COOPGISTemporaryFileName + 
              " http://" + djangoproject.settings.COOPGISServerIPAddress + "/coopgis/serverupdaterepository/")
    File=open(djangoproject.settings.COOPGISTemporaryFileName, 'r')
    FileResultsList=[]
    for char in File.read():
        FileResultsList.append(char)
    File.close()    
    os.system("sudo -u apachescript sudo rm " + djangoproject.settings.COOPGISTemporaryFileName)
    String=''.join(FileResultsList)
    return String

def ClientCopyImageFiles():
    os.system("sudo -u apachescript sudo mkdir /var/www/images") 
    os.system("sudo -u apachescript sudo chmod -R 777 /var/www/images")
    os.system("sudo -u apachescript sudo cp /opt/coopgis/media/images/* /var/www/images/")
    os.system("sudo -u apachescript sudo chmod -R 777 /var/www/images")
    os.system("sudo -u apachescript sudo cp /opt/coopgis/media/images/style.css /var/www/style.css")
    

def ClientDownloadUpdatedRepository(ServerSideDownloadRepositoryLocation):
    import COOPGIS_Misc
    WriteUpdateStatus('Syncing Client Repository with Server')
    os.system("sudo -u apachescript sudo chmod -R 777 /opt/coopgis/")
    #Here, need to:
    #Get all of the Files Lists needed for processing
    RemoteFilesDictionary=COOPGIS_Misc.GetRemoteFile(ServerSideDownloadRepositoryLocation + 'FileDictionary.pickle', PickleIndicator=True)
    RemoteDirectoryList=COOPGIS_Misc.GetRemoteFile(ServerSideDownloadRepositoryLocation + 'DirectoryList.pickle', PickleIndicator=True)
    LocalDirectory, LocalFiles = COOPGIS_Misc.WalkDirectory('/opt/coopgis/')
    #Delete any files that exist locally but are not on the server
    if(len(RemoteFilesDictionary) > 50):  #Crude check to make sure something was received from the server
        for entry in LocalFiles:
            if(not RemoteFilesDictionary.has_key(entry)): 
                    os.system("sudo -u apachescript sudo rm " + entry)
    if(len(RemoteDirectoryList) > 10):  #Crude check to make sure something was received from the server
        for entry in LocalDirectory:
            if(not entry in RemoteDirectoryList):
                os.system("sudo -u apachescript sudo rm -R " + entry)
    #Attempt to Create All directories that exist on the server
    for entry in RemoteDirectoryList:
        os.system("sudo -u apachescript sudo mkdir " + entry) 
    #Download the Database dump file safely
    Tries=0
    while(True):
        os.system("sudo -u apachescript sudo wget -O /opt/coopgis/DataNotPartOfCOOPGIS/Latest.sql http://" + 
                  djangoproject.settings.COOPGISServerIPAddress + '/' + ServerSideDownloadRepositoryLocation + 
                  'opt/coopgis/DataNotPartOfCOOPGIS/Latest.sql')
        os.system("sudo -u apachescript sudo wget -O /opt/coopgis/DataNotPartOfCOOPGIS/RemoteSize.txt http://" + 
                   djangoproject.settings.COOPGISServerIPAddress + '/coopgis/servergetsizeofdatabasefile/')
        RemoteDatabaseFileSizeFile=open('/opt/coopgis/DataNotPartOfCOOPGIS/RemoteSize.txt', 'r')
        try:
            RemoteDatabaseFileSize=int(RemoteDatabaseFileSizeFile.read())
        except:
            raise(Exception("Could not read the size of the RemoteDatabase File (/opt/coopgis/DataNotPartOfCOOPGIS/RemoteSize.txt)"))
        RemoteDatabaseFileSizeFile.close()
        LocateDatabaseFileSize=os.path.getsize('/opt/coopgis/DataNotPartOfCOOPGIS/Latest.sql')
        if(RemoteDatabaseFileSize == LocateDatabaseFileSize):
            break
        if(Tries > 5):
            raise(Exception("Could not download an updated database, aborting update process"))
        Tries = Tries + 1
    #Download Remote Files that either:
    #   A)  Do not Exist Locally
    #   B)  Have a modified time > then the local files modified time
    for entry in RemoteFilesDictionary:
        DownloadIndicator=False
        if(not LocalFiles.has_key(entry)):
            DownloadIndicator=True
        elif(LocalFiles[entry] < RemoteFilesDictionary[entry]):
            DownloadIndicator=True
        if(DownloadIndicator):
            os.system("sudo -u apachescript sudo wget -O " + entry + 
                      " http://" + djangoproject.settings.COOPGISServerIPAddress + '/' + ServerSideDownloadRepositoryLocation[:-1] +
                      entry)
    os.system("sudo -u apachescript sudo chmod -R 777 /opt/coopgis/")
    os.system("sudo -u apachescript sudo mkdir /opt/coopgis/fromgps/anonymousftproot_OtherReadOnly") 
    os.system("sudo -u apachescript sudo mkdir /opt/coopgis/fromgps/anonymousftproot_OtherReadOnly/incomingftpallpermissions")
    os.system("sudo -u apachescript sudo chmod -R 755 /opt/coopgis/fromgps/anonymousftproot_OtherReadOnly") 
    os.system("sudo -u apachescript sudo chmod -R 777 /opt/coopgis/fromgps/anonymousftproot_OtherReadOnly/incomingftpallpermissions")
    #The following line should no longer be necessary, as settings.py looks for the existance of a file that is only on the server
    #os.system("sudo -u apachescript sudo sed -i 's/ServerIndicator=True/ServerIndicator=False/' /opt/coopgis/djangoproject/settings.py")
    
def ClientInstallUpdatedDatabase():
    WriteUpdateStatus('Loading Updated COOPGIS Database [Network Activity is Complete]')
    os.system("sudo -u apachescript sudo sync")
    import django.db
    django.db.close_connection()
    os.system("sudo -u apachescript sudo /etc/init.d/postgresql restart")
    os.system("sudo -u apachescript sudo dropdb coopgis")
    os.system("sudo -u apachescript sudo sync")
    os.system("sudo -u apachescript sudo createdb coopgis")
    os.system('sudo -u apachescript sudo psql coopgis -f /opt/coopgis/DataNotPartOfCOOPGIS/Latest.sql')
    os.system("sudo -u apachescript sudo sync")
    time.sleep(10) #Give a little time for database writing to complete before immediately rebooting

def ClientUpdateBluetoothMacAddressIfNeeded():
    if(not djangoproject.settings.COOPGISInVirtualMachineIndicator):
        import COOPGIS_String
        MACAddress=ReadBlueToothMasterFile()
        CreateConnectToBluetoothScript(MACAddress)    

def WriteUpdateStatus(String):
    try:
        os.system('sudo -u apachescript sudo chmod 777 ' + djangoproject.settings.COOPGISUpdateLogFileName)  
    except:
        pass
    File=open(djangoproject.settings.COOPGISUpdateLogFileName, 'a')
    File.write(str(datetime.datetime.now()) + ':   ' + String + '\n')
    File.close()

def GetLastUpdateDateTime():
    try:
        return datetime.datetime.fromtimestamp(os.path.getmtime(djangoproject.settings.COOPGISUpdateLogFileName))
    except:
        return datetime.datetime(2008, 1, 1)

def GetUpdateStatus():
    os.system("sudo -u apachescript sudo mkdir /opt/coopgis/command") 
    File=open(djangoproject.settings.COOPGISCommandUpdateTemporaryStatusFile)
    FileResultsList=[]
    for char in File.read():
        FileResultsList.append(char)
    File.close()
    Status=''.join(FileResultsList)
    return Status

def ClientPerformUpdateTasks(UpdateNumber): 
    """ClientPeformUpdateTasks runs on a client machine to update it to the latest version.  It Exports the Command Table to a pickle file, 
    sends it to the server, waits for a response file from the server, downloads it, and updates the client with the latest version of COOPGIS.
    The User View is UpdateClientRequest that redirects to the ClientDisplayUpdateStatus view for status updates"""
    if(len(UpdateNumber) <> 22):  #22 character update number is expected (YYYYMMDD_HHMMSS_RRRRRR), otherwise do not do an update
        return index(request) #Return to main menu, an invalid number of digits were entered
    if(djangoproject.settings.COOPGISServerIndicator):
        return index(request) #This function only works on a client machine
    # Get a list of Commands to send to the server in pickle format 
    CommandsToExport, CommandStringList=ClientGenerateExportCommandStringList()
    ClientSendCommandsToServer(CommandStringList, UpdateNumber)
    ClientInstructServerToLoadCommands(UpdateNumber, CommandsToExport.count())
    ClientSetCommandsAsResidingOnServer(CommandsToExport)
    ClientTellServerToProcessCommands(UpdateNumber)
    ServerSideRepositoryLocation = ClientTellServerToRefreshDownloadRepository()
    if('Your Download Location:/var/www/' in ServerSideRepositoryLocation):
        ServerSideRepositoryLocation = ServerSideRepositoryLocation[len('Your Download Location:/var/www/'):]
    else:
        raise Exception('Download location is invalid: ' + ServerSideRepositoryLocation)
    ClientDownloadUpdatedRepository(ServerSideRepositoryLocation) 
    ClientInstallUpdatedDatabase()
    ClientUpdateBluetoothMacAddressIfNeeded()
    ClientCopyImageFiles()

    os.system('sudo -u apachescript sudo mkdir /var/www/music')   #Eventually, move these tasks to their own post update processing function
    os.system('sudo -u apachescript sudo cp /opt/coopgis/media/music/* /var/www/music/')

    WriteUpdateStatus('Rebooting')
    os.system("sudo -u apachescript sudo sync")
    time.sleep(5)
    os.system("sudo -u apachescript sudo reboot")

def ClientTellServerToProcessCommands(UpdateNumber):
    WriteUpdateStatus('Waiting for Server to Complete Command Processing')
    #wget should not be allowed to retry this action; --timeout=0 disables that behavior
    os.system('sudo -u apachescript sudo wget --timeout=0 http://' + djangoproject.settings.COOPGISServerIPAddress + 
              '/coopgis/serverprocesscommands/' + UpdateNumber + '/')

def ClientSetCommandsAsResidingOnServer(Commands):
    for command in Commands:
        command.CommandResidesOnServerIndicator=True
        command.save()

def ClientGenerateExportCommandStringList():
    WriteUpdateStatus('Generating Export Command String List')
    CommandsToExport=Command.objects.filter(CommandResidesOnServerIndicator=False).filter(CommandProcessedIndicator=True).order_by('id')
    NumberOfCommandsSentToServer=len(CommandsToExport)
    CommandStringList=[]
    for i in CommandsToExport:
        CommandStringList.append(i.GetTextString())
    return CommandsToExport, CommandStringList

def ClientSendCommandsToServer(CommandStringList, UpdateNumber):
    from ftplib import FTP
    WriteUpdateStatus('Sending Pickled Dictionaries To Server')
    DictionaryList=[]
    for i in CommandStringList:
        DictionaryList.append(cPickle.loads(str(i)))

    LocalFileName=djangoproject.settings.COOPGISPath + 'command/' + UpdateNumber + '.pickle'
    RemoteFileName=UpdateNumber + '.pickle'
    try:
        os.remove(LocalFileName)
    except:
        pass
    OutputFile=open(LocalFileName, 'wb')
    OutputFile.write(cPickle.dumps(DictionaryList))
    OutputFile.close()
    #os.system('sudo -u apachescript sudo wput --basename ' + djangoproject.settings.COOPGISPath + 'command/ ' + LocalFileName + ' ftp://' + 
    #           djangoproject.settings.COOPGISFTPUpdateUserName + ':' + djangoproject.settings.COOPGISFTPUpdatePassword + '@' + 
    #           djangoproject.settings.COOPGISServerIPAddress)
    ftp=FTP(djangoproject.settings.COOPGISServerIPAddress)
    ftp.login(djangoproject.settings.COOPGISFTPUpdateUserName, djangoproject.settings.COOPGISFTPUpdatePassword)
    ftp.cwd('ftp')
    ftp.storbinary('STOR ' + RemoteFileName, open(LocalFileName))
    ftp.close()
    

def ClientInstructServerToLoadCommands(UpdateNumber, NumberOfCommands):
    """Tells the Server to Load the Commands Into the Database, and Verifies that the number Loaded == The Number Sent, attempting to access:
       """
    WriteUpdateStatus("Instructing Server to Load Commands Into Database:  'sudo -u apachescript sudo wget -O '" + djangoproject.settings.COOPGISCommandTemporaryUploadResultsFileName + 
              ' http://' + djangoproject.settings.COOPGISServerIPAddress + '/coopgis/serverimportcommands/' + UpdateNumber + '/')
    os.system("sudo -u apachescript sudo chmod 777 " + djangoproject.settings.COOPGISCommandTemporaryUploadResultsFileName)
    os.system('sudo -u apachescript sudo wget -O ' + djangoproject.settings.COOPGISCommandTemporaryUploadResultsFileName + 
              ' http://' + djangoproject.settings.COOPGISServerIPAddress + '/coopgis/serverimportcommands/' + UpdateNumber + '/')

    NumberOfCommandsImportedByServer=ClientGetNumberOfCommandsImportedByServer()
    if(NumberOfCommands <> NumberOfCommandsImportedByServer):
        WriteUpdateStatus('Abort, Number of Commands Imported by Server do Not Match Number of Local Commands:  ' + UpdateNumber)
        raise(Exception('Update:  ' + UpdateNumber + ' failed and is aborted.  Number of Commands Uploaded does not match number imported by server'))

def ClientGetNumberOfCommandsImportedByServer():
    InputFile=open(djangoproject.settings.COOPGISCommandTemporaryUploadResultsFileName, 'rb')
    FileResultsList=[]
    for char in InputFile.read():
        FileResultsList.append(char)
    InputFile.close()
    CommandImportResponseByServer=''.join(FileResultsList)
    StartDelimiter='<CommandsImported>'
    EndDelimiter='</CommandsImported>'
    StartIndex=CommandImportResponseByServer.find(StartDelimiter) + len(StartDelimiter)
    EndIndex=CommandImportResponseByServer.find(EndDelimiter)
    if StartIndex - len(StartDelimiter) == -1:
        return 0   #delimiter not in file, most likely due to no local commands; catch already in place if there is a count mismatch
    NumberOfCommandsImportedByServer=int(CommandImportResponseByServer[StartIndex:EndIndex])
    return NumberOfCommandsImportedByServer

def CreateConnectToBluetoothScript(MACAddress):
    FileName=djangoproject.settings.COOPGISBlueToothMacAddressTargetFileName
    FileStart="""#!/bin/bash
        #    Copyright 2008, 2009 Tri-County Electric Cooperative, St. Matthews, South Carolina
        #    This file is part of COOPGIS.
        #    COOPGIS is free software: you can redistribute it and/or modify
        #    it under the terms of the GNU General Public License as published by
        #    the Free Software Foundation, either version 3 of the License, or
        #    (at your option) any later version.
        #    COOPGIS is distributed in the hope that it will be useful,
        #    but WITHOUT ANY WARRANTY; without even the implied warranty of
        #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        #    GNU General Public License for more details.
        #    You should have received a copy of the GNU General Public License
        #    along with COOPGIS.  If not, see <http://www.gnu.org/licenses/>.
        #This File is generated dynamically in the COOPGIS_Update.py file
        #It will be overwritten periodically
        #Modify this file in COOPGIS_Update.py for permanent changes"""
    FileMiddle='\nMACADDRESS="' + MACAddress + '"\n'
    FileEnd="""\nsudo sdptool add --channel=1 OPUSH
        sudo rfcomm unbind /dev/rfcomm0 $MACADDRESS
        sudo rfcomm bind /dev/rfcomm0 $MACADDRESS"""
    try:
        os.remove(FileName)
    except:
        pass
    File=open(FileName, 'w')
    File.write(FileStart + FileMiddle + FileEnd)
    File.close()
    os.system("sudo -u apachescript sudo chmod 777 " + FileName)
    
def ServerWaitUntilEarlierUpdatesAreProcessed(UpdateNumber, InProgressFileName):
    #File Names are 22 character update number (YYYYMMDD_HHMMSS_RRRRRR) + .pickle
    CurrentFileNameOnly=os.path.split(InProgressFileName)[1]
    CurrentOrderedNumber=int(CurrentFileNameOnly[0:8] + CurrentFileNameOnly[9:15] + CurrentFileNameOnly[16:22])
    while(True):
        Directory=os.listdir(djangoproject.settings.COOPGISUpdatePathInProgress)
        ReadyToProceedIndicator=True
        for i in Directory:
            OrderedNumber=int(i[0:8] + i[9:15] + i[16:22])
            if(OrderedNumber < CurrentOrderedNumber):
                ReadyToProceedIndicator=False
        if(ReadyToProceedIndicator):
            break
        time.sleep(30)


def ServerProtectedDumpDatabaseAndPullRepository(IPAddress):
    DatabaseDumpInProgressFileName='/opt/coopgis/DataNotPartOfCOOPGIS/DatabaseDumpInProgress.txt'
    while True:
        if(os.path.exists(DatabaseDumpInProgressFileName)):
            LastModifiedTimestamp=os.path.getmtime(DatabaseDumpInProgressFileName)
            LastModified=datetime.datetime.fromtimestamp(LastModifiedTimestamp)
            #if file is too old, remove; a previous update may have failed mid-process
            if datetime.datetime.now() > LastModified + datetime.timedelta(hours=2):
                os.remove(DatabaseDumpInProgressFileName)
            time.sleep(30)
        else:
            break
    File=open(DatabaseDumpInProgressFileName, 'wb')
    File.write('Temporary File')
    File.close()
    SpecificRepositoryDirectory = djangoproject.settings.COOPGISUpdatePathRepository + IPAddress + '/'
    os.system("sudo -u apachescript sudo rm /opt/coopgis/DataNotPartOfCOOPGIS/Latest.sql") #Ensure the Latest File does not exist on the Server
    os.system("sudo -u apachescript sudo rm -R " + SpecificRepositoryDirectory)
    os.system("sudo -u apachescript sudo mkdir " + SpecificRepositoryDirectory) 
    os.system("sudo -u apachescript sudo mkdir " + SpecificRepositoryDirectory + 'opt/')
    os.system("sudo -u apachescript sudo mkdir " + SpecificRepositoryDirectory + 'opt/coopgis/')
    os.system("sudo -u apachescript sudo mkdir " + SpecificRepositoryDirectory + 'opt/coopgis/DataNotPartOfCOOPGIS')
    os.system("sudo -u apachescript sudo cp -R /opt/coopgis/ " + SpecificRepositoryDirectory + 'opt/')
    DatabaseDumpFileName=(SpecificRepositoryDirectory + 'opt/coopgis/DataNotPartOfCOOPGIS/Latest.sql')
    os.system("sudo -u apachescript rm -f " + DatabaseDumpFileName)  #-f does not prompt and forces a delete of a file if it exists, ignores if not existing
    os.system("sudo -u apachescript sudo chmod -R 777 " + SpecificRepositoryDirectory)
    os.system("sudo -u apachescript sudo -u postgres /usr/bin/pg_dump coopgis > " + DatabaseDumpFileName)
    Directories, Files = COOPGIS_Misc.WalkDirectory('/opt/coopgis/')
    os.system("sudo -u apachescript sudo chmod -R 777 " + SpecificRepositoryDirectory)
    FileDictionaryFile=open(SpecificRepositoryDirectory + 'FileDictionary.pickle', 'wb')
    Results=Files
    pickle.dump(Results, FileDictionaryFile)
    FileDictionaryFile.close()
    DirectoryListFile=open(SpecificRepositoryDirectory + 'DirectoryList.pickle', 'wb')
    Results=Directories
    pickle.dump(Results, DirectoryListFile)
    DirectoryListFile.close()
    os.system("sudo -u apachescript sudo chmod -R 777 " + SpecificRepositoryDirectory)
    try:
        os.remove(DatabaseDumpInProgressFileName)
    except:
        pass
    return SpecificRepositoryDirectory

def ReadBlueToothMasterFile():
    FileName=djangoproject.settings.COOPGISBlueToothMacAddressFileName
    try:
        File=open(FileName, 'r')
    except:
        return 'UnknownMacAddress'
    Results=File.readlines()
    File.close()
    return ''.join(Results) 


